<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    /* //目的：1.调用fn 2.修改fn指向mayCall的第一个参数 3.mayCall的返回值是fn的返回值
    Function.prototype.mayCall = function(context,...fly){
      //因为是fn.mayCall()调用,所以在mayCall中this指向fn这个函数


      //判断mayCall的第一个参数类型

      //1.如果是nll或者undefined则指向window
      if(context === null || context === undefined){
        context = window
      }

      //2.如果是基本数据类型则指向包装对象
      if(typeof context !== "object" && typeof context !== "function"){
        context = Object(context)
      }

      //给第一个参数添加一个属性，值为fn
      const sy1 = Symbol('syl')
      context[sy1] = this

      //调用了fn，并且fn中的this指向context
      const re = context[sy1](...fly)

      //用完sy1这个属性就删除,不要对context产生影响
      delete context[sy1]

      //mayCall方法的返回值设置为fn的返回值
      return re


    }


    function fn(a,b){
      console.log(this,a + b);
      return 666
    }

    const fnResult = fn.mayCall({},1,2)
    console.log(fnResult); */



    //第二遍
    /* Function.prototype.mayCall = function (context, ...fly) {
      if(context === null || context === undefined){
        context = window
      }

      if(typeof context !== "object" && typeof context !== "function"){
        context = Object(context)
      }

      const sy = Symbol('sy')
      context[sy] = this

      const re = context[sy](...fly)

      delete context[sy]

      return re

    }


    function fn(a, b) {
      console.log(this, a + b);
      return 666
    }

    const fnResult = fn.mayCall({},6,6)
    console.log(fnResult); */


    //第三遍
    //调用函数,修改this指向,返回函数的返回值
    /* Function.prototype.mayCall = function (context,...fly) {
      //判断第一个参数的类型
      if(context === null || context === undefined){
        context = window
      }

      if(typeof context !== "object" && typeof context !== "function"){
        context = Object(context)
      }

      //走到这里说明第一个参数是object类型
      const sy = Symbol("sy")
      context[sy] = this

      //constext是fn调用的上下文对象,所以fn的this指向context
      const re = context[sy](...fly)

      delete context[sy]

      //返回fn的返回值
      return re

    }

    function fn(a, b) {
      console.log(this, a * b);
      return 666
    }

    fn.mayCall({},2,3) */






    Function.prototype.mayCall = function(content, ...fly){
      if(content === null || content === undefined){
        content = window
      }

      if(typeof content !== "object" && typeof content !== "function"){
        content = Object(content)
      }

      const sy = Symbol('sy')
      content[sy] = this

      const re = content[sy](...fly)

      delete content[sy]

      return re

    }


    function fn(a,b){
      console.log(this, a * b);
      return 666
    }

    console.log(fn.mayCall({},2,3));



  </script>
</body>

</html>